package com.siecom.transport;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothSocket;
import android.hardware.usb.UsbAccessory;
import android.os.PowerManager;
import android.util.Log;

import com.siecom.constconfig.ConstDefine;
import com.siecom.proto.Message;
import com.siecom.transport.bluetooth.BlueServer;
import com.siecom.transport.handler.FinanHandler;
import com.siecom.transport.handler.FingerPrintHandler;
import com.siecom.transport.handler.IdentityHandler;
import com.siecom.transport.handler.KeyBoardHandler;
import com.siecom.transport.handler.OtherHandler;
import com.siecom.transport.handler.ServiceHandler;
import com.siecom.transport.handler.SignatureHandler;
import com.siecom.transport.handler.UpdateHandler;
import com.siecom.transport.serialport.SerialServer;
import com.siecom.transport.usbport.UsbServer;

import java.util.HashMap;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;


/**
 * Created by zhq on 2016/6/13.
 */
public class Distribution {


    /**
     * 根据命令类型分发
     */
    public static HashMap<Integer, ServiceHandler> handlerMap = new HashMap<Integer, ServiceHandler>();

    static {
        addHandler(ConstDefine.ID_MODULE, new IdentityHandler());
        addHandler(ConstDefine.FINAN_MODULE, new FinanHandler());
        addHandler(ConstDefine.FINGE_MODULE, new FingerPrintHandler());
        addHandler(ConstDefine.KEY_MODULE, new KeyBoardHandler());
//        addHandler(ConstDefine.KEY_MODULE, new KeyBoardHandler2());
//        addHandler(ConstDefine.HEARTBEAT_MODULE,new HeartbeatHandler());
        addHandler(ConstDefine.OTHER_MODULE, new OtherHandler());
        addHandler(ConstDefine.SIGNATURE_MODULE, new SignatureHandler());
        addHandler(ConstDefine.UPDATE_MODULE, new UpdateHandler());
    }

//    private HeartbeatHandler heartbeatHandler = (HeartbeatHandler) handlerMap.get(ConstDefine.HEARTBEAT_MODULE);

    public static BlueServer mBlueServer = new BlueServer();
    public SerialServer serialServer = new SerialServer();
    public UsbServer mUsbServer = new UsbServer();

    public static boolean status = true;

    public Observable<BluetoothSocket> init() {

        Observable<BluetoothSocket> observable = mBlueServer.accept();

        return observable;

    }

    public void closeBT() {

        mBlueServer.close();

    }

    public void closeSerial() {

        serialServer.close();
    }

    public void closeUSBAccessory(){
        mUsbServer.closeAccessory();
    }

    public static void screeSwitch(boolean onOrOff) {

        status = onOrOff;

    }

    public boolean initSerial() {
        boolean b = serialServer.initSerialPort(ConstDefine.OUT_PORT, 115200);
        if (b) {
            serialServer.listenFromSerial();
            return true;
        } else {
            return false;
        }
    }

    public boolean initUSB(UsbAccessory accessory){
        boolean b = mUsbServer.openAccessory(accessory);
        if (b){
            mUsbServer.listenFromUsb();
            return true;
        }else {
            return false;
        }
    }


    public void startListen(ConnectStatusCallback callback) {

//        heartbeatHandler.startHeartbeat(ConstDefine.intervalMs);
//        heartbeatHandler.setConnectStatusCallback(callback);


        Observable<Message.siecomproto> observable = mBlueServer.listen();

        Observer<Message.siecomproto> observer = new Observer<Message.siecomproto>() {

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                // HKBaseApplication.saveCatchInfo2File(e);
                if (callback != null)
                    callback.onDisConnect(e);

            }

            @Override
            public void onComplete() {
                Log.e("listen", "finish");

                // DeviceInterface.allClose();


            }


            @Override
            public void onSubscribe(@NonNull Disposable disposable) {


            }

            @SuppressLint("InvalidWakeLockTag")
            @Override
            public void onNext(Message.siecomproto msg) {

                int module = msg.getModule();


                if (!status) {
                    Log.e("switch", "off");
                    return;
                }
                if (handlerMap.containsKey(module)) {
                    ServiceHandler handler = handlerMap.get(module);
                    handler.onReceive(mBlueServer, msg,"");


                }

            }
        };

        observable.subscribe(observer);

    }
    PowerManager pm;
    PowerManager.WakeLock wl;
    public static void addHandler(Integer module, ServiceHandler handler) {

        handlerMap.put(module, handler);

    }

    public static void removeHandler(Integer module) {

        handlerMap.remove(module);
    }


}
